home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume89 / unix / shel302a.2 < prev    next >
Text File  |  1989-03-15  |  51KB  |  2,249 lines

  1. Path: xanth!nic.MR.NET!hal!cwjcc!tut.cis.ohio-state.edu!bloom-beacon!apple!bbn!ulowell!page
  2. From: page@swan.ulowell.edu (Bob Page)
  3. Newsgroups: comp.sources.amiga
  4. Subject: v89i059:  shell - csh-like command interpreter v3.02a, Part02/03
  5. Message-ID: <12243@swan.ulowell.edu>
  6. Date: 15 Mar 89 19:39:22 GMT
  7. Organization: University of Lowell, Computer Science Dept.
  8. Lines: 2238
  9. Approved: page@swan.ulowell.edu
  10.  
  11. Submitted-by: PERUGIA@ICNUCEVM.BITNET (Cesare Dieni)
  12. Posting-number: Volume 89, Issue 59
  13. Archive-name: unix/shell302a.2
  14.  
  15. #    This is a shell archive.
  16. #    Remove everything above and including the cut line.
  17. #    Then run the rest of the file through sh.
  18. #----cut here-----cut here-----cut here-----cut here----#
  19. #!/bin/sh
  20. # shar:    Shell Archiver
  21. #    Run the following text with /bin/sh to create:
  22. #    comm1.c
  23. #    comm2.c
  24. #    execom.c
  25. # This archive created: Wed Mar 15 14:15:18 1989
  26. cat << \SHAR_EOF > comm1.c
  27. /*
  28.  * COMM1.C
  29.  *
  30.  * Matthew Dillon, August 1986
  31.  *
  32.  * Version 2.07M by Steve Drew 10-Sep-87
  33.  *
  34.  * Version 3.02A by Carlo Borreo & Cesare Dieni 20-Dec-88
  35.  *
  36.  */
  37.  
  38. extern char *v_passed, *v_gotofwd, *v_cwd, *v_lasterr;
  39.  
  40. #define DIR_SHORT 0x01
  41. #define DIR_FILES 0x02
  42. #define DIR_DIRS  0x04
  43.  
  44. extern int has_wild;
  45. char cwd[256];
  46.  
  47. /*
  48.     Parse the options specified in sw[]
  49.     Setting a bit in global variable options
  50.     for each one found
  51. */
  52.  
  53. get_opt(sw,count)
  54. char *sw;
  55. int *count;
  56. {
  57. register char *c,*s;
  58. unsigned int l,i = 0;
  59.  
  60. options=0;
  61. while((++i < ac) && (av[i][0] == '-')) {
  62.     for (c = av[i]+1; *c ; c++) {
  63.         for(l = 0,s = sw;*s && *s != *c; ++s) ++l;
  64.         if (*s) options |= (1 << l);
  65.         }
  66.     }
  67. *count = i;
  68. }
  69.  
  70. do_sleep()
  71. {
  72. int i;
  73.  
  74. if (ac == 2) {
  75.     i = atoi(av[1]);
  76.     while (i > 0) { Delay (100L); i -= 2; if (CHECKBREAK()) break; }
  77.     }
  78. return 0;
  79. }
  80.  
  81. do_protect()
  82. {
  83. register long mask=0xf;
  84. register char *s, *p, *flags="DEWRAPSH";
  85. register unsigned int i;
  86. for (s=av[--ac]; *s; s++)
  87.     if (p=index(flags,Toupper(*s))) mask^=(1 << (p-flags));
  88.     else ierror(av[ac],500);
  89. for (i=1; i<ac; i++) if (!SetProtection(av[i],mask)) pError(av[i]);
  90. return 0;
  91. }
  92.  
  93. do_filenote()
  94. {
  95. char *note=av[--ac];
  96. register unsigned int i;
  97.  
  98. for (i=1; i<ac; i++) if (!SetComment(av[i], note)) pError(av[i]);
  99. return 0;
  100. }
  101.  
  102. do_cat()
  103. {
  104. FILE *fopen(), *fi;
  105. register unsigned int lctr;
  106. unsigned int i;
  107. char buf[256];
  108.  
  109. get_opt("n",&i);
  110. if (i>=ac) {
  111.     if (has_wild) { printf("No files matching\n"); return 20; }
  112.     while (gets(buf) && !dobreak()) {
  113.         if (options) printf("%4d ",++lctr);
  114.         puts(buf);
  115.         }
  116.     }
  117. for (; i<ac; i++)
  118.     if (fi = fopen (av[i], "r")) {
  119.         lctr=0;
  120.         while (fgets(buf,256,fi) && !dobreak()) {
  121.             if (options) printf("%4d ",++lctr);
  122.             printf("%s",buf);
  123.             }
  124.         fclose (fi);
  125.         }
  126.     else pError(av[i]);
  127. return 0;
  128. }
  129.  
  130. do_info()
  131. {
  132. BPTR lock;
  133. struct InfoData *info;
  134. unsigned int size, free;
  135. char *p,*s,*state;
  136. struct DirectoryEntry *de_head=NULL, *de;
  137.  
  138. info=(struct InfoData *)AllocMem((long)sizeof(struct InfoData),MEMF_PUBLIC);
  139. AddDADevs(&de_head, DLF_DEVICES | DLF_DISKONLY );
  140. Myprocess->pr_WindowPtr = (APTR)(-1);
  141. printf ("Unit  Size  Bytes  Used Blk/By-Free Full Errs  Status    Name\n");
  142. for (de=de_head; de; de=de->de_Next) {
  143.     printf("%-5s",de->de_Name);
  144.     if (lock=Lock(de->de_Name,ACCESS_READ)) {
  145.         if (Info(lock, info)) {
  146.         s = get_pwd(lock);
  147.         if (p=index(s,':')) *p = '\0';
  148.         size = ((info->id_NumBlocks + 2)* info->id_BytesPerBlock)/ 1024;
  149.         free = (((info->id_NumBlocks-info->id_NumBlocksUsed))*
  150.                info->id_BytesPerBlock)/ 1024;
  151.         switch(info->id_DiskState) {
  152.             case ID_WRITE_PROTECTED: state="Read Only "; break;
  153.             case ID_VALIDATED:     state="Read/Write"; break;
  154.             case ID_VALIDATING:     state="Validating"; break;
  155.             }
  156.         printf("%4d%c%6ld%7ld%7ld%4d%c%4ld%%%4ld  %s %s\n",
  157.             (size>1024) ? ((size+512) >> 10) : size,
  158.             (size>1024) ? 'M' : 'K',
  159.             info->id_BytesPerBlock,
  160.             info->id_NumBlocksUsed,
  161.             info->id_NumBlocks-info->id_NumBlocksUsed,
  162.             (free>1024) ? ((free+512) >> 10) : free,
  163.             (free>1024) ? 'M' : 'K',
  164.             (info->id_NumBlocksUsed * 100)/info->id_NumBlocks,
  165.             info->id_NumSoftErrors,
  166.             state,
  167.             s);
  168.         }
  169.         else pError (de->de_Name);
  170.         UnLock(lock);
  171.         }
  172.     else puts("  No disk present");
  173.     }
  174. FreeDAList(&de_head);
  175. Myprocess->pr_WindowPtr = NULL;
  176. FreeMem(info,(long)sizeof(struct InfoData));
  177. return 0;
  178. }
  179.  
  180. /* things shared with display_file */
  181.  
  182. char lspec[128];
  183. int filecount, col;
  184. long bytes, blocks;
  185.  
  186. /*
  187.  * the args passed to do_dir will never be expanded
  188.  */
  189. do_dir()
  190. {
  191.    void display_file();
  192.    int i;
  193.  
  194.    col = filecount = 0;
  195.    bytes = blocks = 0L;
  196.    *lspec = '\0';
  197.  
  198.    get_opt("sfd",&i);
  199.  
  200.    if (ac == i) {
  201.       ++ac;
  202.       av[i] = "";
  203.    }
  204.    if (!(options & (DIR_FILES | DIR_DIRS)))  options|=(DIR_FILES | DIR_DIRS);
  205.  
  206.    for (; i < ac; ++i) {
  207.       char **eav;
  208.       int c,eac;
  209.       if (!(eav = expand(av[i], &eac)))
  210.       continue;
  211.       QuickSort(eav, eac);
  212.       for(c=0;c < eac && !breakcheck();++c) display_file(options,eav[c]);
  213.       free_expand (eav);
  214.       if (CHECKBREAK()) break;
  215.    }
  216.    if (col)  printf("\n");
  217.    if (filecount > 1) {
  218.       blocks += filecount; /* account for dir blocks */
  219.       printf (" %ld Blocks, %ld Bytes used in %d files\n", blocks, bytes, filecount);
  220.    }
  221.    return 0;
  222. }
  223.  
  224. void
  225. display_file(options,filestr)
  226. int options;
  227. char *filestr;
  228. {
  229.    long atol();
  230.    int isadir,slen;
  231.    char sc;
  232.    char *c,*s,*fi;
  233.    BPTR lock;
  234.  
  235. /*    if current dir different from lspec then
  236.     look for ':' or '/' if found lock it and get_pwd.
  237.     else then use cwd.
  238. */
  239.    for(s = c = filestr; *c; ++c) if (*c == ':' || *c == '/') s = c;
  240.    if (*s == ':') ++s;
  241.    sc = *s;
  242.    *s = '\0';
  243.    c = filestr;
  244.    if (!*c) c = cwd;
  245.    if (strcmp (c, &lspec))  {
  246.     strcpy(lspec, c);
  247.     if (col) printf("\n");
  248.     if (lock=Lock(c,SHARED_LOCK)) {
  249.         printf("Directory of %s\n", get_pwd(lock));
  250.         UnLock(lock);
  251.         }
  252.     col = 0;
  253.     }
  254.    *s = sc;
  255.    if (sc == '/') s++;
  256.    slen = strlen(s);
  257.    fi = s + slen + 1;
  258.    isadir = (fi[12] =='D');
  259.  
  260.    if (!(((options & DIR_FILES) && !isadir) ||
  261.       ((options & DIR_DIRS) &&  isadir)))
  262.       return;
  263.    if (isadir) printf ("\23333m");
  264.    if (options & DIR_SHORT) {
  265.     if (col==3 && slen>18) { printf("\n"); col = 0; }
  266.     if (slen>18) { printf(" %-37s",s); col+= 2; }
  267.         else { printf(" %-18s",s); col++; }
  268.     if (col > 3) { printf("\n"); col=0; }
  269.     }
  270.    else printf("   %-24s %s",s ,fi);
  271.    if (isadir) printf("\2330m");
  272.    fflush(stdout);
  273.    fi[16] = fi[21] = '\0';
  274.    bytes  += atol(fi+10);
  275.    blocks += atol(fi+17);
  276.    filecount++;
  277.    return;
  278. }
  279.  
  280. do_quit()
  281. {
  282. if (Src_stack) {
  283.     Quit = 1;
  284.     return(do_return());
  285.     }
  286. main_exit(0);
  287. }
  288.  
  289. do_echo(str)
  290. register char *str;
  291. {
  292. char nl=1;
  293.  
  294. for (; *str && *str != ' '; ++str);
  295. if (*str==' ') ++str;
  296. if (av[1] && !strcmp(av[1],"-n")) {
  297.     nl = 0;
  298.     str += 2;
  299.     if (*str==' ') ++str;
  300.     }
  301. printf("%s",str);
  302. if (nl) printf("\n");
  303. fflush(stdout);
  304. return 0;
  305. }
  306.  
  307. /* gets a line from file, joining two lines if the first ends in '\' */
  308.  
  309. char *myfgets(buf, buflen, file)
  310. char *buf;
  311. FILE *file;
  312. {
  313. char *bufptr=buf;
  314. int remain=buflen, n, flag;
  315.  
  316. do {
  317.     if (fgets(bufptr, remain, file)==NULL) {
  318.         if (remain != buflen)
  319.             fprintf(stderr,"Source: file ends in '\\'\n");
  320.         return NULL;
  321.         }
  322.     n=strlen(buf);
  323.     bufptr += n;
  324.     if (flag= (*(bufptr-2)=='\\')) bufptr-=2;
  325.     remain -= (n+2);
  326.     } while (flag);
  327. return buf;
  328. }
  329.  
  330. do_source(str)
  331. char *str;
  332. {
  333. register FILE *fi;
  334. char buf[256];
  335.  
  336. if (Src_stack == MAXSRC) {
  337.     ierror(NULL,217);
  338.     return -1;
  339.     }
  340. if ((fi = fopen (av[1], "r")) == 0) { pError(av[1]); return -1;    }
  341. set_var(LEVEL_SET, v_passed, next_word(next_word(str)));
  342. ++H_stack;
  343. Src_pos[Src_stack] = 0;
  344. Src_base[Src_stack] = (long)fi;
  345. ++Src_stack;
  346. while (myfgets (buf, 256, fi) && !dobreak()) {
  347.     int len = strlen(buf);
  348.     buf[len-1] = '\0';
  349.     Src_pos[Src_stack - 1] += len;
  350.     if (Verbose && !forward_goto) fprintf(stderr,"%s\n",buf);
  351.     exec_command (buf);
  352.     }
  353. --H_stack;
  354. --Src_stack;
  355. if (forward_goto) ierror(NULL,501);
  356. forward_goto = 0;
  357. unset_level(LEVEL_LABEL + Src_stack);
  358. unset_var(LEVEL_SET, v_gotofwd);
  359. unset_var(LEVEL_SET, v_passed);
  360. fclose (fi);
  361. return 0;
  362. }
  363.  
  364. /*
  365.  * return ptr to string that contains full cwd spec.
  366.  */
  367. char *get_pwd(flock)
  368. BPTR flock;
  369. {
  370. static char pwdstr[130];
  371. PathName(flock, pwdstr, 128L);
  372. return pwdstr;
  373. }
  374.  
  375. /*
  376.  * set process cwd name and $_cwd, if str != NULL also print it.
  377.  */
  378. do_pwd(str)
  379. char *str;
  380. {
  381. char *ptr;
  382.  
  383. if (Myprocess->pr_CurrentDir == 0)
  384.     attempt_cd(":"); /* if we just booted 0 = root lock */
  385. strcpy(cwd,get_pwd(Myprocess->pr_CurrentDir,1));
  386. if (str) puts(cwd);
  387. set_var(LEVEL_SET, v_cwd, cwd);
  388. /* put the current dir name in our CLI task structure */
  389. CtoBStr(cwd, Mycli->cli_SetName, 128L);
  390. }
  391.  
  392. /*
  393.  * CD
  394.  *
  395.  * CD(str, 0)      -do CD operation.
  396.  *
  397.  *    standard operation: breakup path by '/'s and process independantly
  398.  *    x:    -reset cwd base
  399.  *    ..    -remove last cwd element
  400.  *    N     -add N or /N to cwd
  401.  */
  402.  
  403. do_cd(str)
  404. char *str;
  405. {
  406.    char sc, *ptr;
  407.    int err=0;
  408.  
  409.    str = next_word(str);
  410.    if (*str == '\0') {
  411.       puts(cwd);
  412.       return(0);
  413.    }
  414.    str[strlen(str)+1] = '\0';        /* add second \0 on end */
  415.    while (*str) {
  416.       for (ptr = str; *ptr && *ptr != '/' && *ptr != ':'; ++ptr);
  417.       switch (*ptr) {
  418.       case ':':
  419.       sc = ptr[1];
  420.       ptr[1] = '\0';
  421.       err = attempt_cd(str);
  422.       ptr[1] = sc;
  423.       break;
  424.       case '\0':
  425.       case '/':
  426.       *ptr = '\0';
  427.       if (strcmp(str, "..") == 0 || str == ptr)
  428.          str = "/";
  429.       if (*str) err = attempt_cd(str);
  430.       break;
  431.       }
  432.       if (err) break;
  433.       str = ptr + 1;
  434.    }
  435.    do_pwd(NULL);      /* set $_cwd */
  436.    return err;
  437. }
  438.  
  439. attempt_cd(str)
  440. char *str;
  441. {
  442. BPTR oldlock, filelock;
  443.  
  444. if (filelock=Lock(str, ACCESS_READ)) {
  445.     if (isdir(str)) {
  446.         if (oldlock=CurrentDir(filelock)) UnLock(oldlock);
  447.         return (0);
  448.         }
  449.     UnLock(filelock);
  450.     ierror(str, 212);
  451.     }
  452. else ierror(str, 205);
  453. return -1;
  454. }
  455.  
  456. do_mkdir()
  457. {
  458. register unsigned int i;
  459. BPTR lock;
  460.  
  461. for (i=1; i<ac; ++i) {
  462.     if (exists(av[i])) ierror(av[i],203);
  463.     else if (lock=CreateDir(av[i])) UnLock (lock);
  464.     else pError(av[i]);
  465.     }
  466. return 0;
  467. }
  468.  
  469. do_mv()
  470. {
  471. char *dest, buf[256];
  472. int dirflag;
  473. register unsigned int i;
  474.  
  475. dirflag=isdir(dest=av[--ac]);
  476. if (ac>3 && !dirflag) { ierror(dest, 507); return (-1); }
  477. for (i=1; i<ac; ++i) {
  478.     strcpy(buf, dest);
  479.     if (dirflag) TackOn(buf, BaseName(av[i]));
  480.     if (Rename(av[i], buf)==0)
  481.         { pError(av[i]); return -1; }
  482.     }
  483. return 0;
  484. }
  485.  
  486. int dirstoo;
  487.  
  488. all_args(args, action, dirsflag)
  489. char *args;
  490. int (*action)();
  491. {
  492. unsigned int i;
  493.  
  494. get_opt(args, &i);
  495. dirstoo=dirsflag;
  496. for (; i<ac && !dobreak(); ++i)
  497.     if (isdir(av[i])) {
  498.         if (options & 1) recurse(av[i], action);
  499.             else if (dirstoo) (*action)(av[i]);
  500.         }
  501.     else (*action)(av[i]);
  502. return 0;
  503. }
  504.  
  505. char *searchstring;
  506.  
  507. search_file(s)
  508. char *s;
  509. {
  510. FILE *fopen(), *fi;
  511. unsigned int lctr, len=strlen(searchstring);
  512. int yesno;
  513. char buf[256], lowbuf[256], first;
  514. register char *p, *l, *t;
  515.  
  516. if (!(options & 2)) for (t=searchstring; *t=Toupper(*t); t++);
  517. first=*searchstring;
  518. if ((fi=fopen(s, "r"))==NULL) { pError(s); return; }
  519. lctr=0;
  520. if (!(options & 32)) printf("Examining %s...\n",s);
  521. while (fgets(buf,256,fi) && !dobreak()) {
  522.     lctr++;
  523.     if (options & 4) yesno=compare_ok(searchstring,buf);
  524.     else {
  525.         yesno=0;
  526.         p=buf;
  527.         if (!(options & 2)) {
  528.             l=lowbuf;            /* p is already =buf */
  529.             while (*l++=Toupper(*p++));    /* lowbuf=upper(buf) */
  530.             p=lowbuf;
  531.             }
  532.         while (p=index(p,first))
  533.             if (!strncmp(p++,searchstring,len)) { yesno=1; break; }
  534.         }
  535.     if (yesno ^ ((options & 16)!=0) ) {
  536.             /* default: print line numbers */
  537.         if (!(options & 8)) printf("%4d ",lctr);
  538.         printf("%s",buf);
  539.         }
  540.     }
  541. fclose (fi);
  542. }
  543.  
  544. do_search()
  545. {
  546. searchstring=av[--ac];
  547. all_args("rcwneq", search_file, 0);
  548. return 0;
  549. }
  550.  
  551. rm_file(file)
  552. char *file;
  553. {
  554. if (has_wild) printf(" %s...",file);
  555. if (options & 2) SetProtection(file,0L);
  556. if (!DeleteFile(file)) pError (file); else if (has_wild) printf("Deleted\n");
  557. }
  558.  
  559. do_rm()
  560. {
  561. all_args("rp", rm_file, 1);
  562. return 0;
  563. }
  564.  
  565. recurse(name, action)
  566. char *name;
  567. int (*action)();
  568. {
  569. register BPTR lock, cwd;
  570. register FIB *fib=(FIB *)AllocMem((long)sizeof(FIB),MEMF_PUBLIC);
  571. char *namecopy=malloc(256);
  572.  
  573. if (name[0] =='\0') return;
  574. namecopy[0]=0;
  575. if (lock=Lock(name,ACCESS_READ)) {
  576.     cwd =CurrentDir(lock);
  577.     if (Examine(lock, fib))
  578.     while (ExNext(lock, fib) && !CHECKBREAK()) {
  579.         if (*namecopy) { (*action)(namecopy); namecopy[0]=0; }
  580.         if (fib->fib_DirEntryType>=0) recurse(fib->fib_FileName,action);
  581.         else strcpy(namecopy,fib->fib_FileName);
  582.         }
  583.     if (*namecopy) (*action)(namecopy);
  584.     UnLock(CurrentDir(cwd));
  585.     if (dirstoo) (*action)(name);
  586.     }
  587. else pError(name);
  588. free(namecopy);
  589. FreeMem(fib, (long)sizeof(FIB));
  590. }
  591.  
  592. do_history()
  593. {
  594. register struct HIST *hist;
  595. int i = H_tail_base;
  596. int len = (av[1]) ? strlen(av[1]) : 0;
  597.  
  598. for (hist = H_tail; hist && !dobreak(); hist = hist->prev)
  599.     if (len == 0 || !strncmp(av[1], hist->line, len))
  600.         printf("%3d %s\n", i++, hist->line);
  601. return 0;
  602. }
  603.  
  604. do_mem()
  605. {
  606. long cfree, ffree;
  607. extern long AvailMem();
  608.  
  609. Forbid();
  610. cfree = AvailMem (MEMF_CHIP);
  611. ffree = AvailMem (MEMF_FAST);
  612. Permit();
  613. if (ffree) printf ("FAST memory: %ld\nCHIP memory: %ld\n", ffree, cfree);
  614. printf("Total  Free: %ld\n", cfree+ffree);
  615. return 0;
  616. }
  617.  
  618. /* forline i RAM:temp echo line $_linenum: $i */
  619.  
  620. do_forline()
  621. {
  622. char vname[33], buf[256];
  623. register unsigned short lctr;
  624. FILE *f;
  625. char *cstr;
  626. static char *linenumname="_linenum";
  627.  
  628. strcpy(vname,av[1]);
  629. f=fopen(av[2],"r");
  630. if (f==NULL) pError(av[2]);
  631. lctr=0;
  632. ++H_stack;
  633. cstr = compile_av (av, 3, ac, ' ');
  634. while (fgets(buf,256,f) && !dobreak()) {
  635.     buf[strlen(buf)-1]='\0';    /* remove CR */
  636.     lctr++;
  637.     set_var(LEVEL_SET, vname, buf);
  638.     sprintf(buf,"%d",lctr);
  639.     set_var(LEVEL_SET, linenumname, buf);
  640.     exec_command(cstr);
  641.     }
  642. fclose(f);
  643. --H_stack;
  644. free (cstr);
  645. unset_var (LEVEL_SET, vname);
  646. unset_var (LEVEL_SET, linenumname);
  647. return 0;
  648. }
  649.  
  650. /* fornum i 1 10 echo $i */
  651.  
  652. do_fornum()
  653. {
  654. char vname[33], buf[16];
  655. int n1, n2;
  656. char *cstr;
  657. register int i;
  658.  
  659. strcpy(vname,av[1]);
  660. n1=myatoi(av[2],0 ,32767); if (Errno) return 20;
  661. n2=myatoi(av[3],n1,    32767); if (Errno) return 20;
  662. ++H_stack;
  663. cstr = compile_av (av, 4, ac, ' ');
  664. for (i=n1; i<=n2 && !CHECKBREAK(); i++) {
  665.     sprintf(buf,"%d",i);
  666.     set_var (LEVEL_SET, vname, buf);
  667.     exec_command(cstr);
  668.     }
  669. --H_stack;
  670. free (cstr);
  671. unset_var (LEVEL_SET, vname);
  672. return 0;
  673. }
  674.  
  675. /*
  676.  * foreach var_name  ( str str str str... str ) commands
  677.  * spacing is important (unfortunately)
  678.  *
  679.  * ac=0    1 2 3 4 5 6 7
  680.  * foreach i ( a b c ) echo $i
  681.  * foreach i ( *.c ) "echo -n "file ->";echo $i"
  682.  */
  683.  
  684. do_foreach()
  685. {
  686. register int cstart, cend;
  687. register char *cstr;
  688. char **fav;
  689. char vname[33];
  690. int i;
  691.  
  692. get_opt("v",&i);
  693. strcpy(vname, av[i++]);
  694. if (*av[i] == '(') i++;
  695. cstart = i;
  696. while (i<ac && *av[i] != ')') i++;
  697. if (i > ac) { fprintf(stderr,"')' expected\n"); return 20; }
  698. ++H_stack;
  699. cend = i;
  700.  
  701. fav = (char **)malloc(sizeof(char *) * (ac));
  702. cstr = compile_av (av, cend + 1, ac, ' ');
  703.  
  704. for (i = cstart; i < cend; ++i) fav[i] = av[i];
  705.  
  706. for (i = cstart; i<cend && !CHECKBREAK(); ++i) {
  707.     set_var (LEVEL_SET, vname, fav[i]);
  708.     if (options & 1) printf("foreach: %s\n", fav[i]);
  709.     exec_command(cstr);
  710.     }
  711. --H_stack;
  712. free (fav);
  713. free (cstr);
  714. unset_var (LEVEL_SET, vname);
  715. return 0;
  716. }
  717.  
  718. do_forever(str)
  719. char *str;
  720. {
  721. int rcode = 0;
  722. char *ptr = next_word(str);
  723.  
  724. ++H_stack;
  725. for (;;) {
  726.     if (CHECKBREAK()) { rcode = 20; break; }
  727.     if (exec_command (ptr) < 0) {
  728.         str = get_var(LEVEL_SET, v_lasterr);
  729.         rcode = (str) ? atoi(str) : 20;
  730.         break;
  731.         }
  732.     }
  733. --H_stack;
  734. return rcode;
  735. }
  736.  
  737. do_exec(str)
  738. char *str;
  739. {
  740. return exec_command(next_word(str));
  741. }
  742.  
  743. extern struct Window *w;
  744. extern struct IntuitionBase *IntuitionBase;
  745.  
  746. do_window()
  747. {
  748. long x, y, maxwidth, maxheight, arg[5];
  749. unsigned int i;
  750. struct Screen *screen;
  751. struct Window *window;
  752.  
  753. get_opt("slfbaq", &i);
  754. if (options & 1)
  755.     SizeWindow(w, (long)(w->MinWidth-w->Width), (long)(w->MinHeight-w->Height));
  756. if (options & 2) {
  757.     x=-w->LeftEdge;
  758.     y=-w->TopEdge;
  759.     MoveWindow(w,x,y);
  760.     x=IntuitionBase->ActiveScreen->Width -w->Width;
  761.     y=IntuitionBase->ActiveScreen->Height-w->Height;
  762.     SizeWindow(w,x,y);
  763.     }
  764. if (options & 4) WindowToFront(w);
  765. if (options & 8) WindowToBack(w);
  766. if (options & 16) ActivateWindow(w);
  767. if(ac >= 5) {
  768.     for(i=1; i<5; i++) {
  769.         arg[i] = myatoi(av[i],0,1023);
  770.         if (Errno) return 20;
  771.         }
  772.     maxwidth = w->WScreen->Width;
  773.     maxheight= w->WScreen->Height;
  774.     if (arg[3] > maxwidth - arg[1] || arg[4] > maxheight- arg[2]) {
  775.         ierror(NULL, 500);
  776.         return 20;
  777.         }
  778.     x = -w->LeftEdge;
  779.     y = -w->TopEdge;
  780.     MoveWindow(w, x, y);
  781.     x = arg[3] - w->Width;
  782.     y = arg[4] - w->Height;
  783.     SizeWindow(w, x, y);
  784.     x = arg[1];
  785.     y = arg[2];
  786.     MoveWindow(w, x, y);
  787.     }
  788. if(options & 32) {
  789.     for (screen=IntuitionBase->FirstScreen; screen; screen=screen->NextScreen) {
  790.         printf("\nScreen \"%s\" (%d,%d,%dx%d):\n",
  791.             screen->Title,
  792.             screen->LeftEdge,
  793.             screen->TopEdge,
  794.             screen->Width,
  795.             screen->Height
  796.             );
  797.         for (window=screen->FirstWindow; window; window=window->NextWindow) {
  798.         printf("\tWindow\t\"%s\" (%d,%d,%dx%d)\n",
  799.             window->Title,
  800.             window->LeftEdge,
  801.             window->TopEdge,
  802.             window->Width,
  803.             window->Height
  804.             );
  805.         }
  806.         }
  807.     return 0;
  808.     }
  809. Delay(25L); /* pause 1/2 sec. before trying to print */
  810. printf("\014");
  811. return 0;
  812. }
  813.  
  814. setsystemtime(ds)
  815. struct DateStamp *ds;
  816. {
  817. struct timerequest tr;
  818. long secs= ds->ds_Days*86400 + ds->ds_Minute*60 + ds->ds_Tick/TICKS_PER_SECOND;
  819.  
  820. if (OpenDevice(TIMERNAME, UNIT_VBLANK, &tr, 0L)) {
  821.     fprintf(stderr,"Clock error: can't open timer device\n");
  822.     return;
  823.     }
  824. tr.tr_node.io_Message.mn_Node.ln_Type = NT_MESSAGE;
  825. tr.tr_node.io_Message.mn_Node.ln_Pri = 0L;
  826. tr.tr_node.io_Message.mn_Node.ln_Name = NULL;
  827. tr.tr_node.io_Message.mn_ReplyPort = NULL;
  828. tr.tr_node.io_Command = TR_SETSYSTIME;
  829. tr.tr_time.tv_secs = secs;
  830. tr.tr_time.tv_micro = 0L;
  831. if (DoIO (&tr)) fprintf(stderr,"Clock error: can't talk to timer device\n");
  832. CloseDevice (&tr);
  833. }
  834.  
  835. char tday[10];
  836.  
  837. char *dates(dss)
  838. struct DateStamp *dss;
  839. {
  840. static char timestr[40];
  841. char tdate[10], ttime[10];
  842. struct DateTime dt;
  843. struct DateStamp *myds=&(dt.dat_Stamp);
  844.  
  845. dt.dat_Format=FORMAT_DOS;
  846. dt.dat_StrDay=tday;
  847. dt.dat_StrDate=tdate;
  848. dt.dat_StrTime=ttime;
  849. dt.dat_Flags=NULL;
  850. myds->ds_Days=dss->ds_Days;
  851. myds->ds_Minute=dss->ds_Minute;
  852. myds->ds_Tick=dss->ds_Tick;
  853. StamptoStr(&dt);
  854. sprintf(timestr,"%s %s\n",tdate,ttime);
  855. timestr[18]='\n';
  856. timestr[19]='\0';    /* protection against bad timestamped files */
  857. return timestr;
  858. }
  859.  
  860. date()
  861. {
  862. struct DateStamp dss;
  863. register unsigned short i;
  864. struct DateTime dt;
  865.  
  866. dt.dat_Format=FORMAT_DOS;
  867. if (ac==1) {
  868.     DateStamp(&dss);
  869.     printf("%s %s",tday,dates(&dss));
  870.     }
  871. else {
  872.     DateStamp(& (dt.dat_Stamp));
  873.     for (i=1; i<ac; i++) {
  874.         dt.dat_StrDate=NULL;
  875.         dt.dat_StrTime=NULL;
  876.         dt.dat_Flags=DTF_FUTURE;
  877.         if (index(av[i],':')) dt.dat_StrTime=av[i];
  878.             else dt.dat_StrDate=av[i];
  879.         if (StrtoStamp(&dt)) ierror(av[i],500);
  880.         }
  881.     setsystemtime( & (dt.dat_Stamp) );
  882.     }
  883. return 0;
  884. }
  885. SHAR_EOF
  886. cat << \SHAR_EOF > comm2.c
  887. /*
  888.  * COMM2.C
  889.  *
  890.  * (c)1986 Matthew Dillon     9 October 1986
  891.  *
  892.  * Version 2.07M by Steve Drew 10-Sep-87
  893.  *
  894.  * Version 3.02A by Carlo Borreo & Cesare Dieni 20-Dec-88
  895.  *
  896.  */
  897.  
  898. extern char *v_gotofwd;
  899.  
  900. /* Casting conveniences */
  901. #define BPTR_TO_C(strtag, var)  ((struct strtag *)(BADDR( (ULONG) var)))
  902. #define PROC(task)              ((struct Process *)task)
  903. #define CLI(proc)               (BPTR_TO_C(CommandLineInterface, proc->pr_CLI))
  904.  
  905. /* Externs */
  906. extern int has_wild;                    /* flag set if any arg has a ? or * */
  907.  
  908. /* globals */
  909. int cp_update;
  910. int cp_date;
  911.  
  912. do_abortline()
  913. {
  914. Exec_abortline = 1;
  915. return 0;
  916. }
  917.  
  918. do_return()
  919. {
  920. register int retcode=(ac<2 ? 0 : atoi(av[1]));
  921.    Exec_abortline = 1;
  922.    if (Src_stack) {
  923.        FILE *ptr = (FILE *)Src_base[Src_stack - 1];
  924.        ptr->_bp = ptr->_bend;
  925.        ptr->_flags |= _EOF;
  926. /*     fseek (Src_base[Src_stack - 1], 0L, 2); */
  927.       return retcode;
  928.    } else main_exit(retcode);
  929. }
  930.  
  931. /*
  932.  * STRHEAD
  933.  *
  934.  * place a string into a variable removing everything after and including
  935.  * the 'break' character
  936.  *
  937.  * strhead varname breakchar string
  938.  *
  939.  */
  940.  
  941. do_strhead()
  942. {
  943. char *s;
  944. if (s=index(av[3],*av[2])) *s='\0';
  945. set_var (LEVEL_SET, av[1], av[3]);
  946. return 0;
  947. }
  948.  
  949. do_strtail()
  950. {
  951. char *s;
  952. if (s=index(av[3],*av[2])) s++; else s=av[3];
  953. set_var (LEVEL_SET, av[1], s);
  954. return 0;
  955. }
  956.  
  957. long dptrtosecs(d)
  958. struct DPTR *d;
  959. {
  960. register struct DateStamp *ds=(&d->fib->fib_Date);
  961. return ds->ds_Days*86400 + ds->ds_Minute*60 + ds->ds_Tick/TICKS_PER_SECOND;
  962. }
  963.  
  964. long timeof(s)
  965. char *s;
  966. {
  967. struct DPTR *d;
  968. int dummy;
  969. long n;
  970.  
  971. if ( (d=dopen(s,&dummy))==NULL ) return 0L;
  972. n=dptrtosecs(d);
  973. dclose(d);
  974. return n;
  975. }
  976.  
  977. /*
  978.  * if -f file (exists) or:
  979.  *
  980.  * if A < B   <, >, =, <=, >=, <>, where A and B are either:
  981.  * nothing
  982.  * a string
  983.  * a value (begins w/ number)
  984.  */
  985.  
  986. do_if(garbage, com)
  987. char *garbage;
  988. {
  989. int result;
  990. int i;
  991.  
  992. switch (com) {
  993.     case 0:
  994.     if (If_stack && If_base[If_stack - 1]) If_base[If_stack++] = 1;
  995.     else {
  996.         get_opt("rftmdn",&i);
  997.         result=evalif(i);
  998.         If_base[If_stack++]=(options & 32 ? result : !result);
  999.         }
  1000.     break;
  1001.     case 1:
  1002.     if (If_stack > 1 && If_base[If_stack - 2]) break;
  1003.     if (If_stack) If_base[If_stack - 1] ^= 1;
  1004.     break;
  1005.     case 2:
  1006.     if (If_stack) --If_stack;
  1007.     break;
  1008.      }
  1009. disable = (If_stack) ? If_base[If_stack - 1] : 0;
  1010. if (If_stack >= MAXIF) {
  1011.     fprintf(stderr,"If's too deep\n");
  1012.     disable = If_stack = 0;
  1013.     return -1;
  1014.     }
  1015. if (forward_goto) disable = If_base[If_stack - 1] = 0;
  1016. return 0;
  1017. }
  1018.  
  1019. evalif(i)
  1020. register unsigned int i;
  1021. {
  1022. char c;
  1023. long num, t0;
  1024. long AvailMem();
  1025.  
  1026. switch(options & ~32) {
  1027.     case 0:
  1028.     if (ac-i != 3) return (ac>i && *av[i]);
  1029.     Errno=0;
  1030.     num=Atol(av[i])-Atol(av[i+2]);
  1031.     if (Errno) num=strcmp(av[i],av[i+2]);
  1032.     if (num < 0)       c='<';
  1033.     else if (num > 0)  c='>';
  1034.     else if (num == 0) c='=';
  1035.     return index(av[i+1], c) != NULL;
  1036.     case 1:
  1037.     return do_rpn(NULL,i);
  1038.     case 2:
  1039.     return exists(av[i]);
  1040.     case 4:
  1041.     t0=timeof(av[i++]);
  1042.     for ( ; i<ac ; i++)
  1043.         if (t0<=timeof(av[i])) return 1;
  1044.     return 0;
  1045.     case 8:
  1046.     return (AvailMem( (long)MEMF_FAST )!=0);
  1047.     case 16:
  1048.     return (isdir(av[i])!=0);
  1049.     default:
  1050.     ierror(NULL,500);
  1051.     return 0;
  1052.     }
  1053. }
  1054.  
  1055. do_label()
  1056. {
  1057.    char aseek[32];
  1058.  
  1059.    if (Src_stack == 0) {
  1060.       ierror (NULL, 502);
  1061.       return (-1);
  1062.    }
  1063.  
  1064.    sprintf (aseek, "%ld %d", Src_pos[Src_stack-1], If_stack);
  1065.    set_var (LEVEL_LABEL + Src_stack - 1, av[1], aseek);
  1066.    if (!strcmp(av[1],get_var(LEVEL_SET,v_gotofwd)))
  1067.       forward_goto = 0;
  1068.    return 0;
  1069. }
  1070.  
  1071. do_goto()
  1072. {
  1073.    int new;
  1074.    long pos;
  1075.    char *lab;
  1076.  
  1077.    if (Src_stack == 0) {
  1078.       ierror (NULL, 502);
  1079.    } else {
  1080.       lab = get_var (LEVEL_LABEL + Src_stack - 1, av[1]);
  1081.       if (lab == NULL) {
  1082.          forward_goto = 1;
  1083.          set_var (LEVEL_SET, v_gotofwd, av[1]);
  1084.          return(0);
  1085.       } else {
  1086.          pos = atoi(lab);
  1087.          fseek (Src_base[Src_stack - 1], pos, 0);
  1088.          Src_pos[Src_stack - 1] = pos;
  1089.          new = atoi(next_word(lab));
  1090.          for (; If_stack < new; ++If_stack)
  1091.             If_base[If_stack] = 0;
  1092.          If_stack = new;
  1093.       }
  1094.    }
  1095.    Exec_abortline = 1;
  1096.    return (0);      /* Don't execute rest of this line */
  1097. }
  1098.  
  1099.  
  1100. do_inc(garbage, com)
  1101. char *garbage;
  1102. {
  1103. char *var, num[32];
  1104.  
  1105. if (ac>2) com *= atoi(av[2]);
  1106. if (var = get_var (LEVEL_SET, av[1])) {
  1107.     sprintf (num, "%d", atoi(var)+com);
  1108.     set_var (LEVEL_SET, av[1], num);
  1109.     }
  1110. return 0;
  1111. }
  1112.  
  1113. do_input()
  1114. {
  1115. char in[256], *p,*s;
  1116. unsigned int i;
  1117.  
  1118. for (i=1; i < ac; ++i)
  1119.     if (gets(in)) {
  1120.     for(p = in; *p; p = s) {
  1121.         s = next_word(p);
  1122.         if (*s) *(s-1) = 0xA0;
  1123.         }
  1124.     set_var (LEVEL_SET, av[i], in);
  1125.     }
  1126. return 0;
  1127. }
  1128.  
  1129. do_ver()
  1130. {
  1131. puts("Shell V3.02A\n\
  1132. (c)1986 Matthew Dillon\n\
  1133. Manx (M) versions by Steve Drew\n\
  1134. ARP (A) versions by Carlo Borreo & Cesare Dieni\n");
  1135. return 0;
  1136. }
  1137.  
  1138. do_ps()
  1139. {
  1140. /* this code fragment based on ps.c command by Dewi Williams */
  1141.  
  1142. register int    count;        /* loop variable        */
  1143. struct Task    *task;        /* EXEC descriptor        */
  1144. char        strbuf[64+1];    /* scratch for btocstr()    */
  1145. char        cmd[40+1];    /* holds cmd name        */
  1146. long ncli;
  1147.  
  1148. printf("Proc Command Name         CLI Type    Pri.  Address  Directory\n");
  1149. Forbid();
  1150.  
  1151. ncli=(long)FindCLI(0L);
  1152. for (count = 1; count <= ncli ; count++)
  1153.         /* or just assume 20?*/
  1154.     if (task = (struct Task *)FindCLI((long)count)) {
  1155.     if (task==NULL) continue;
  1156.     /* Sanity check just in case */
  1157.     if (PROC(task)->pr_TaskNum == 0 || PROC(task)->pr_CLI == 0) continue;
  1158.                             /* or complain? */
  1159.     BtoCStr(cmd,   CLI(PROC(task))->cli_CommandName, 40L);
  1160.     BtoCStr(strbuf,CLI(PROC(task))->cli_SetName    , 64L);
  1161.     printf("%2d   %-20.20s %-11.11s %3d  %8lx  %s\n",
  1162.         count,
  1163.         cmd,
  1164.         task->tc_Node.ln_Name,
  1165.         task->tc_Node.ln_Pri,
  1166.         task,
  1167.         strbuf);
  1168.     }
  1169. Permit();
  1170. return 0;
  1171. }
  1172.  
  1173. /*
  1174.  * CP [-d] [-u] file file
  1175.  * CP [-d] [-u] file file file... destdir
  1176.  * CP [-r][-u][-d] dir dir dir... destdir
  1177.  */
  1178.  
  1179. char *errstr;          /* let's be alittle more informative */
  1180.  
  1181. do_copy()
  1182. {
  1183. register int recur, ierr;
  1184. register char *destname;
  1185. register char destisdir;
  1186. register FIB *fib;
  1187. int i;
  1188.  
  1189. errstr = "";
  1190. ierr = 0;
  1191.  
  1192. fib = (FIB *)AllocMem((long)sizeof(FIB), MEMF_PUBLIC);
  1193.  
  1194. get_opt("rud",&i);
  1195. recur     = (options & 0x01);
  1196. cp_update = (options & 0x02);
  1197. cp_date   = (!(options & 0x04)); /* the default is keep orignal file date */
  1198.  
  1199. destname = av[ac - 1];
  1200.  
  1201. if (ac < i + 2) {
  1202.     ierr = 500;
  1203.     goto done;
  1204.     }
  1205. destisdir = isdir(destname);
  1206. if (ac > i + 2 && !destisdir) {
  1207.     ierr = 507;
  1208.     goto done;
  1209.     }
  1210.  
  1211. /*
  1212.  * copy set:                        reduce to:
  1213.  *    file to file                     file to file
  1214.  *    dir  to file (NOT ALLOWED)
  1215.  *    file to dir                      dir to dir
  1216.  *    dir  to dir                      dir to dir
  1217.  *
  1218.  */
  1219.  
  1220. for (; i<ac-1 && !dobreak(); ++i) {
  1221.     short srcisdir = isdir(av[i]);
  1222.     if (srcisdir && has_wild && (ac >2)) /* hack to stop dir's from */
  1223.         continue;             /* getting copied if specified */
  1224.                          /* from wild expansion */
  1225.     if (srcisdir) {
  1226.         BPTR srcdir, destdir;
  1227.         if (!destisdir) {
  1228.             if (exists(destname)) {
  1229.                 ierr = 507;    /* disallow dir to file */
  1230.                 goto done;
  1231.                 }
  1232.             if (destdir = CreateDir(destname)) UnLock(destdir);
  1233.             destisdir = 1;
  1234.             }
  1235.         if (!(destdir = Lock(destname, ACCESS_READ))) {
  1236.             ierr = 205;
  1237.             errstr = destname;
  1238.             goto done;
  1239.             }
  1240.         if (!(srcdir = Lock(av[i], ACCESS_READ))) {
  1241.             ierr = 205;
  1242.             errstr = av[i];
  1243.             UnLock(destdir);
  1244.             goto done;
  1245.             }
  1246.         ierr = copydir(srcdir, destdir, recur);
  1247.         UnLock(srcdir);
  1248.         UnLock(destdir);
  1249.         if (ierr) break;
  1250.         }
  1251.     else {        /* FILE to DIR,   FILE to FILE   */
  1252.         BPTR destdir, srcdir, tmp;
  1253.         char *destfilename;
  1254.  
  1255.         srcdir = (BPTR)(Myprocess->pr_CurrentDir);
  1256.  
  1257.         if ((tmp = Lock(av[i], ACCESS_READ)) == NULL || !Examine(tmp,fib)) {
  1258.             if (tmp) UnLock(tmp);
  1259.             ierr = 205;
  1260.             errstr = av[i];
  1261.             goto done;
  1262.             }
  1263.         UnLock(tmp);
  1264.         if (destisdir) {
  1265.             destdir = Lock(destname, ACCESS_READ);
  1266.             destfilename = fib->fib_FileName;
  1267.             }
  1268.         else {
  1269.             destdir = srcdir;
  1270.             destfilename = destname;
  1271.             }
  1272.         printf(" %s..",av[i]);
  1273.         fflush(stdout);
  1274.         ierr = copyfile(av[i], srcdir, destfilename, destdir);
  1275.         if (destisdir) UnLock(destdir);
  1276.         if (ierr) break;
  1277.         }
  1278.     }
  1279.  
  1280. done:
  1281.  
  1282. FreeMem(fib, (long)sizeof(FIB));
  1283. if (ierr) {
  1284.     ierror(errstr, ierr);
  1285.     return(20);
  1286.     }
  1287. return 0;
  1288. }
  1289.  
  1290.  
  1291. copydir(srcdir, destdir, recur)
  1292. register BPTR srcdir, destdir;
  1293. {
  1294.    BPTR cwd;
  1295.    register FIB *srcfib;
  1296.    register BPTR destlock, srclock;
  1297.    int ierr;
  1298.    static int level;
  1299.  
  1300.    level++;
  1301.    ierr = 0;
  1302.    srcfib = (FIB *)AllocMem((long)sizeof(FIB), MEMF_PUBLIC);
  1303.    if (Examine(srcdir, srcfib)) {
  1304.       while (ExNext(srcdir, srcfib)) {
  1305.          if (CHECKBREAK())
  1306.             break;
  1307.          if (srcfib->fib_DirEntryType < 0) {
  1308.             printf("%*s%s..",(level-1) * 6," ",srcfib->fib_FileName);
  1309.             fflush(stdout);
  1310.             ierr = copyfile(srcfib->fib_FileName,srcdir,srcfib->fib_FileName,destdir);
  1311.             if (ierr)
  1312.                break;
  1313.          } else {
  1314.             if (recur) {
  1315.                cwd = CurrentDir(srcdir);
  1316.                if (srclock = Lock(srcfib->fib_FileName, ACCESS_READ)) {
  1317.                   CurrentDir(destdir);
  1318.                   if (!(destlock = Lock(srcfib->fib_FileName))) {
  1319.                      destlock = CreateDir(srcfib->fib_FileName);
  1320.                      printf("%*s%s (Dir)....[Created]\n",(level-1) * 6,
  1321.                                 " ",srcfib->fib_FileName);
  1322.  
  1323.                         /* UnLock and re Lock if newly created
  1324.                            for file_date() to work properly
  1325.                         */
  1326.                      if (destlock) UnLock(destlock);
  1327.                      destlock = Lock(srcfib->fib_FileName);
  1328.                   }
  1329.                   else
  1330.                      printf("%*s%s (Dir)\n",(level-1) * 6," ",srcfib->fib_FileName);
  1331.                   if (destlock) {
  1332.                      ierr = copydir(srclock, destlock, recur);
  1333.                      UnLock(destlock);
  1334.                   } else {
  1335.                      ierr = (int)((long)IoErr());
  1336.                   }
  1337.                   UnLock(srclock);
  1338.                } else {
  1339.                   ierr = (int)((long)IoErr());
  1340.                }
  1341.                CurrentDir(cwd);
  1342.                if (ierr)
  1343.                   break;
  1344.             }
  1345.          }
  1346.       }
  1347.    } else {
  1348.       ierr = (int)((long)IoErr());
  1349.    }
  1350.    --level;
  1351.    FreeMem(srcfib, (long)sizeof(FIB));
  1352.    return(ierr);
  1353. }
  1354.  
  1355.  
  1356. copyfile(srcname, srcdir, destname, destdir)
  1357. char *srcname, *destname;
  1358. BPTR srcdir, destdir;
  1359. {
  1360. BPTR cwd;
  1361. BPTR f1, f2;
  1362. long i;
  1363. int stat,ierr;
  1364. char *buf;
  1365. struct DPTR *dp, *dps = NULL;
  1366.  
  1367. if ((buf = (char *)AllocMem(8192L, MEMF_PUBLIC|MEMF_CLEAR))==NULL)
  1368.     { ierr = 103; goto fail; }
  1369. ierr = 0;
  1370. cwd = CurrentDir(srcdir);
  1371. if ((f1=Open(srcname, MODE_OLDFILE))==NULL)
  1372.     { errstr = srcname; ierr = 205; goto fail; }
  1373. dps = dopen(srcname,&stat);
  1374. CurrentDir(destdir);
  1375. if (cp_update)
  1376.     {
  1377.     dp=dopen(destname, &stat);
  1378.     if ( dptrtosecs(dp) >= dptrtosecs(dps) &&
  1379.         !strcmp(dps->fib->fib_FileName, dp->fib->fib_FileName))
  1380.         { dclose(dp); Close(f1); printf("..not newer\n"); goto fail; }
  1381.     dclose(dp);
  1382.     }
  1383. if ((f2=Open(destname, MODE_NEWFILE))==NULL)
  1384.     { Close(f1); ierr = (int)((long)IoErr()); errstr=destname; goto fail;  }
  1385. while (i = Read(f1, buf, 8192L))
  1386.     if (Write(f2, buf, i) != i) { ierr = (int)((long)IoErr()); break; }
  1387. Close(f2);
  1388. Close(f1);
  1389. if (!ierr)
  1390.     {
  1391.     if (cp_date) file_date(&dps->fib->fib_Date, destname);
  1392.     printf("..copied\n");
  1393.     }
  1394. else DeleteFile(destname);
  1395. fail:
  1396.  dclose(dps);
  1397.  if (buf) FreeMem(buf, 8192L);
  1398.  CurrentDir(cwd);
  1399.  return(ierr);
  1400. }
  1401.  
  1402. do_touch()
  1403. {
  1404. struct DateStamp ds;
  1405. register unsigned int i;
  1406. DateStamp(&ds);
  1407. for (i=1; i<ac; i++) if (file_date(&ds, av[i])) ierror(av[i],500);
  1408. return 0;
  1409. }
  1410.  
  1411. file_date(date,name)
  1412. struct DateStamp *date;
  1413. char *name;
  1414. {
  1415. long packargs[7];
  1416. UBYTE *ptr;
  1417. struct MsgPort *task;
  1418. BPTR dirlock;
  1419. struct DPTR *tmp;
  1420. int stat;
  1421.  
  1422. if (!(task = (struct MsgPort *)DeviceProc(name))) return(1);
  1423. if (tmp = dopen(name, &stat)) {
  1424.     dirlock = ParentDir(tmp->lock);
  1425.     ptr=AllocMem(65L,MEMF_PUBLIC);
  1426.     CtoBStr(tmp->fib->fib_FileName,(ULONG)ptr >> 2L,64L);
  1427.     dclose(tmp);
  1428.     packargs[1]=dirlock;
  1429.     packargs[2]=(ULONG)ptr >> 2L;
  1430.     packargs[3]=(long)date;
  1431.     SendPacket(ACTION_SET_DATE,packargs,task);
  1432.     UnLock(dirlock);
  1433.     FreeMem(ptr,65L);
  1434.     }
  1435. return 0;
  1436. }
  1437.  
  1438. do_addbuffers()
  1439. {
  1440. long packargs[7];
  1441. long n;
  1442. struct MsgPort *task=(struct MsgPort *)DeviceProc(av[1]);
  1443.  
  1444. if (!task) { ierror(av[1],510); return 20; }
  1445. n=myatoi(av[2],1,32767); if (Errno) return 20;
  1446. packargs[0]=n;
  1447. SendPacket(ACTION_MORE_CACHE,packargs,task);
  1448. return 0;
  1449. }
  1450.  
  1451. do_relabel()
  1452. {
  1453. long packargs[7];
  1454. UBYTE *ptr;
  1455. long n;
  1456. struct MsgPort *task=(struct MsgPort *)DeviceProc(av[1]);
  1457.  
  1458. if (!task) { ierror(av[1],510); return 20; }
  1459. ptr=AllocMem(65L,MEMF_PUBLIC);
  1460. CtoBStr(av[2],(ULONG)ptr >> 2L,64L);
  1461. packargs[0]=(ULONG)ptr >> 2L;
  1462. SendPacket(ACTION_RENAME_DISK,packargs,task);
  1463. FreeMem(ptr,65L);
  1464. changedisk(task);
  1465. return 0;
  1466. }
  1467.  
  1468. do_diskchange()
  1469. {
  1470. struct MsgPort *task=(struct MsgPort *)DeviceProc(av[1]);
  1471.  
  1472. if (!task) { ierror(av[1],510); return 20; }
  1473. changedisk(task);
  1474. return 0;
  1475. }
  1476.  
  1477. changedisk(task)
  1478. struct MsgPort *task;
  1479. {
  1480. long packargs[7];
  1481.  
  1482. packargs[0]=1L;
  1483. SendPacket(ACTION_INHIBIT,packargs,task);
  1484. packargs[0]=0L;
  1485. SendPacket(ACTION_INHIBIT,packargs,task);
  1486. }
  1487. SHAR_EOF
  1488. cat << \SHAR_EOF > execom.c
  1489. /*
  1490.  * EXECOM.C
  1491.  *
  1492.  * Matthew Dillon, 10 August 1986
  1493.  *    Finally re-written.
  1494.  *
  1495.  * Version 2.07M by Steve Drew 10-Sep-87
  1496.  *
  1497.  * Version 3.02A by Carlo Borreo & Cesare Dieni 20-Dec-88
  1498.  *
  1499.  */
  1500.  
  1501. extern char *v_histnum, *v_except;
  1502.  
  1503. #define F_EXACT 0
  1504. #define F_ABBR  1
  1505.  
  1506. #define ST_COND   0x01
  1507. #define ST_NORED  0x02
  1508. #define ST_NOEXP  0x04
  1509. #define ST_AV     0x08 /* delimit args within a variable */
  1510.  
  1511. int has_wild = 0;                 /* set if any arg has wild card */
  1512.  
  1513. struct COMMAND {
  1514.     int (*func)();
  1515.     short minargs;
  1516.     short stat;
  1517.     int val;
  1518.     char *name;
  1519. };
  1520.  
  1521. extern char *format_insert_string();
  1522. extern char *mpush(), *exarg();
  1523.  
  1524. extern int do_strleft(), do_strright(), do_strmid(), do_strlen();
  1525. extern int do_fornum(), do_forline(), do_exec();
  1526. extern int do_diskchange(), do_stack(), do_fault(), do_path(), do_pri();
  1527. extern int do_rpn(), do_resident(), do_truerun(), do_aset(), do_howmany();
  1528. extern int do_open(), do_close(), do_fileslist(), do_htype();
  1529. extern int do_run(), do_number(), do_assign(), do_join();
  1530. extern int do_quit(), do_set_var(), do_unset_var();
  1531. extern int do_echo(), do_source(), do_mv(), do_addbuffers();
  1532. extern int do_cd(), do_pwd(), do_rm(), do_mkdir(), do_history();
  1533. extern int do_mem(), do_cat(), do_dir(), do_info(), do_inc();
  1534. extern int do_foreach(), do_return(), do_if(), do_label(), do_goto();
  1535. extern int do_input(), do_ver(), do_sleep(), do_help();
  1536. extern int do_strhead(), do_strtail(), do_relabel();
  1537. extern int do_copy(), date(), do_protect(), do_ps();
  1538. extern int do_forever(), do_abortline(), do_strings(), do_touch();
  1539. extern int do_window(), do_search(), do_filenote();
  1540. char *push_cpy();
  1541.  
  1542. static struct COMMAND Command[] = {
  1543. do_run,        0, ST_AV,    0,    "\001",   /* may call do_source */
  1544. do_set_var,    0, 0, LEVEL_ALIAS,    "alias",  /* uses avline */
  1545. do_abortline,    0, 0,        0,    "abortline",
  1546. do_addbuffers,    2, 0,        0,    "addbuffers",
  1547. do_aset,    1, 0,        0,    "aset",
  1548. do_assign,    0, 0,        0,    "assign",
  1549. do_cat,        0, 0,        0,    "cat",
  1550. do_cd,        0, 0,        0,    "cd",
  1551. do_close,    0, 0,        0,    "close",
  1552. do_copy,    1, 0,        0,    "copy",
  1553. do_copy,    1, 0,        0,    "cp",
  1554. date,        0, 0,        0,    "date",
  1555. do_rm,        0, 0,        0,    "delete",
  1556. do_dir,        0, ST_NOEXP,    0,    "dir",
  1557. do_diskchange,    1, 0,        0,    "diskchange",
  1558. do_inc,        1, 0,        -1,    "dec",
  1559. do_echo,    0, 0,        0,    "echo", /* uses avline */
  1560. do_if,        0, ST_COND,    1,    "else",
  1561. do_if,        0, ST_COND,    2,    "endif",
  1562. do_exec,    1, 0,        0,    "exec",
  1563. do_fault,    1, 0,        0,    "fault",
  1564. do_filenote,    2, 0,        0,    "filenote",
  1565. do_fileslist,    0, 0,        0,    "flist",
  1566. do_foreach,    3, ST_NORED,    0,    "foreach",
  1567. do_forever,    1, ST_NORED,    0,    "forever",
  1568. do_forline,    3, ST_NORED,    0,    "forline",
  1569. do_fornum,    4, ST_NORED,    0,    "fornum",
  1570. do_goto,    1, 0,        0,    "goto",
  1571. do_help,    0, 0,        0,    "help",
  1572. do_history,    0, 0,        0,    "history",
  1573. do_howmany,    0, 0,        0,    "howmany",
  1574. do_htype,    1, 0,        0,    "htype",
  1575. do_if,        1, ST_COND|ST_NORED,0,    "if",
  1576. do_inc,        1, 0,        1,    "inc",
  1577. do_info,    0, 0,        0,    "info",
  1578. do_join,    2, 0,        1,    "join",
  1579. do_input,    1, 0,        0,    "input",
  1580. do_label,    1, ST_COND,    0,    "label",
  1581. do_dir,        0, ST_NOEXP,    0,    "ls",
  1582. do_mkdir,    0, 0,        0,    "md",
  1583. do_mem,        0, 0,        0,    "mem",
  1584. do_mkdir,    0, 0,        0,    "mkdir",
  1585. do_mv,        2, 0,        0,    "mv",
  1586. do_open,    3, 0,        0,    "open",
  1587. do_path,    0, 0,        0,    "path",
  1588. do_pri,        2, 0,        0,    "pri",
  1589. do_protect,    2, 0,        0,    "protect",
  1590. do_ps,        0, 0,        0,    "ps",
  1591. do_pwd,        0, 0,        0,    "pwd",
  1592. do_quit,    0, ST_NORED,    0,    "quit",
  1593. do_truerun,    1, ST_NORED,    1,    "rback",
  1594. do_mv,        2, 0,        0,    "rename",
  1595. do_relabel,    2, 0,        0,    "relabel",
  1596. do_resident,    0, 0,        0,    "resident",
  1597. do_return,    0, 0,        0,    "return",
  1598. do_rm,        0, 0,        0,    "rm",
  1599. do_rpn,        0, ST_NOEXP|ST_NORED,0,    "rpn",
  1600. do_truerun,    1, ST_NORED,    0,    "run",
  1601. do_search,    2, 0,        0,    "search",
  1602. do_set_var,    0, ST_AV, LEVEL_SET,    "set",
  1603. do_sleep,    0, 0,        0,    "sleep",
  1604. do_source,    0, ST_NORED|ST_AV, 0,    "source", /* uses avline */
  1605. do_stack,    0, 0,        0,    "stack",
  1606. do_strhead,    3, 0,        0,    "strhead",
  1607. do_strings,    1, 0,        0,    "strings",
  1608. do_strleft,    3, 0,        0,    "strleft",
  1609. do_strlen,    2, 0,        0,    "strlen",
  1610. do_strmid,    3, 0,        0,    "strmid",
  1611. do_strright,    3, 0,        0,    "strright",
  1612. do_strtail,    3, 0,        0,    "strtail",
  1613. do_touch,    0, 0,        0,    "touch",
  1614. do_cat,        0, 0,        0,    "type",
  1615. do_unset_var,    0, 0, LEVEL_ALIAS,    "unalias",
  1616. do_unset_var,    0, 0, LEVEL_SET  ,    "unset",
  1617. do_ver,        0, 0,        0,    "version",
  1618. do_window,    0, ST_NOEXP,    0,    "window",
  1619. '\0',        0, 0,        0,    NULL
  1620. };
  1621.  
  1622. static unsigned char elast;        /* last end delimeter */
  1623. static char Cin_ispipe, Cout_ispipe;
  1624.  
  1625. exec_command(base)
  1626. char *base;
  1627. {
  1628. register char *scr;
  1629. char buf[32];
  1630.  
  1631. if (!H_stack) {
  1632.     add_history(base);
  1633.     sprintf(buf, "%d", H_tail_base + H_len);
  1634.     set_var(LEVEL_SET, v_histnum, buf);
  1635.     }
  1636. scr = malloc((strlen(base) << 2) + 2);
  1637. preformat(base, scr);
  1638. return (fcomm(scr, 1) ? -1 : 1);
  1639. }
  1640.  
  1641. isalphanum(c)
  1642. register char c;
  1643. {
  1644. return (
  1645.     (c >= '0' && c <= '9') ||
  1646.     (c >= 'a' && c <= 'z') ||
  1647.     (c >= 'A' && c <= 'Z') ||
  1648.     (c == '_')
  1649.     );
  1650. }
  1651.  
  1652. preformat(s, d)
  1653. register char *s, *d;
  1654. {
  1655. register int si, di, qm;
  1656.  
  1657. si = di = qm = 0;
  1658. while (s[si] == ' ' || s[si] == 9) ++si;
  1659. while (s[si]) {
  1660.     if (qm && s[si] != '\"' && s[si] != '\\') {
  1661.         d[di++] = s[si++] | 0x80;
  1662.         continue;
  1663.         }
  1664.     switch (s[si]) {
  1665.         case ' ':
  1666.         case 9:
  1667.             d[di++] = ' ';
  1668.             while (s[si] == ' ' || s[si] == 9) ++si;
  1669.             if (s[si] == 0 || s[si] == '|' || s[si] == ';') --di;
  1670.             break;
  1671.         case '*':
  1672.         case '?':
  1673.             d[di++] = 0x80;
  1674.         case '!':
  1675.             d[di++] = s[si++];
  1676.             break;
  1677.         case '#':
  1678.             d[di++] = '\0';
  1679.             while (s[si]) ++si;
  1680.             break;
  1681.         case ';':
  1682.         case '|':
  1683.             d[di++] = s[si++];
  1684.             while (s[si] == ' ' || s[si] == 9) ++si;
  1685.             break;
  1686.         case '\\':
  1687.             d[di++] = s[++si] | 0x80;
  1688.             if (s[si]) ++si;
  1689.             break;
  1690.         case '\"':
  1691.             qm = 1 - qm;
  1692.             ++si;
  1693.             break;
  1694.         case '^':
  1695.             d[di++] = s[++si] & 0x1F;
  1696.             if (s[si]) ++si;
  1697.             break;
  1698.         case '$': /* search end of var name and place false space */
  1699.             d[di++] = 0x80;
  1700.             d[di++] = s[si++];
  1701.             while (isalphanum(s[si])) d[di++] = s[si++];
  1702.             d[di++] = 0x80;
  1703.             break;
  1704.         default:
  1705.             d[di++] = s[si++];
  1706.             break;
  1707.         }
  1708.     }
  1709. d[di++]=0;
  1710. d[di]=0;
  1711. if (debug) fprintf (stderr,"PREFORMAT: %d :%s:\n", strlen(d), d);
  1712. }
  1713.  
  1714. extern BPTR extOpen();
  1715.  
  1716. /*
  1717.  * process formatted string.  ' ' is the delimeter.
  1718.  *
  1719.  *    0: check '\0': no more, stop, done.
  1720.  *    1: check $.     if so, extract, format, insert
  1721.  *    2: check alias. if so, extract, format, insert. goto 1
  1722.  *    3: check history or substitution, extract, format, insert. goto 1
  1723.  *
  1724.  *    4: assume first element now internal or disk based command.
  1725.  *
  1726.  *    5: extract each ' ' or 0x80 delimited argument and process, placing
  1727.  *       in av[] list (except 0x80 args appended).  check in order:
  1728.  *
  1729.  *             '$'         insert string straight
  1730.  *             '>'         setup stdout
  1731.  *             '>>'        setup stdout flag for append
  1732.  *             '<'         setup stdin
  1733.  *             '*' or '?'  do directory search and insert as separate args.
  1734.  *
  1735.  *             ';' 0 '|'   end of command.  if '|' setup stdout
  1736.  *                          -execute command, fix stdin and out (|) sets
  1737.  *                           up stdin for next guy.
  1738.  */
  1739.  
  1740.  
  1741. fcomm(str, freeok)
  1742. register char *str;
  1743. {
  1744.    static int alias_count;
  1745.    int p_alias_count = 0;
  1746.    char *istr;
  1747.    char *nextstr;
  1748.    char *command;
  1749.    char *pend_alias = NULL;
  1750.    char err = 0;
  1751.    has_wild = 0;
  1752.  
  1753.    ++alias_count;
  1754.  
  1755.    mpush_base();
  1756.    if (*str == 0)
  1757.       goto done1;
  1758. step1:
  1759.    if (alias_count == MAXALIAS || ++p_alias_count == MAXALIAS) {
  1760.       fprintf(stderr,"Alias Loop\n");
  1761.       err = 20;
  1762.       goto done1;
  1763.    }
  1764. /*
  1765.    if (str[1] == '$') {
  1766.       if (istr = get_var (LEVEL_SET, str + 2))
  1767.          str = format_insert_string(str, istr, &freeok);
  1768.    }
  1769. */
  1770.    istr = NULL;
  1771.    if (*(unsigned char *)str < 0x80)
  1772.       istr = get_var (LEVEL_ALIAS, str);  /* only if not \command */
  1773.    *str &= 0x7F;                          /* remove \ teltail     */
  1774.    if (istr) {
  1775.       if (*istr == '%') {
  1776.          pend_alias = istr;
  1777.       } else {
  1778.          str = format_insert_string(str, istr, &freeok);
  1779.          goto step1;
  1780.       }
  1781.    }
  1782.    if (*str == '!') {
  1783.       char *p, c;                     /* fix to allow !cmd1;!cmd2 */
  1784.       for(p = str; *p && *p != ';' ; ++p);
  1785.       c = *p;
  1786.       *p = '\0';
  1787.       istr = get_history(str);
  1788.       *p = c;
  1789.       replace_head(istr);
  1790.       str = format_insert_string(str, istr, &freeok);
  1791.       goto step1;
  1792.    }
  1793.    nextstr = str;
  1794.    command = exarg(&nextstr);
  1795.    if (*command == 0)
  1796.       goto done0;
  1797.    if (pend_alias == 0) {
  1798.       if (cmd_stat(command) & ST_COND)
  1799.          goto skipgood;
  1800.    }
  1801.    if (disable || forward_goto) {
  1802.       while (elast && elast != ';' && elast != '|')
  1803.          exarg(&nextstr);
  1804.       goto done0;
  1805.    }
  1806. skipgood:
  1807.    {
  1808.       register char *arg, *ptr, *scr;
  1809.       short redir;
  1810.       short doexpand;
  1811.       short cont;
  1812.       short inc;
  1813.  
  1814.       ac = 1;
  1815.       av[0] = command;
  1816. step5:                                          /* ac = nextac */
  1817.       if (!elast || elast == ';' || elast == '|')
  1818.          goto stepdone;
  1819.  
  1820.       av[ac] = '\0';
  1821.       cont = 1;
  1822.       doexpand = redir = inc = 0;
  1823.  
  1824.       while (cont && elast) {
  1825.          int cstat = cmd_stat(command);
  1826.  
  1827.          ptr = exarg(&nextstr);
  1828.          inc = 1;
  1829.          arg = "";
  1830.          cont = (elast == 0x80);
  1831.          switch (*ptr) {
  1832.          case '<':
  1833.             redir = -2;
  1834.          case '>':
  1835.             if (cstat & (ST_NORED | ST_COND)) {
  1836.                                                         /* don't extract   */
  1837.                 redir = 0;                              /* <> stuff if its */
  1838.                 arg = ptr;                              /* external cmd.   */
  1839.                 break;
  1840.             }
  1841.             ++redir;
  1842.             arg = ptr + 1;
  1843.             if (*arg == '>') {
  1844.                redir = 2;        /* append >> */
  1845.                ++arg;
  1846.             }
  1847.             cont = 1;
  1848.             break;
  1849.          case '$':
  1850.             /* restore args if from set command or pend_alias */
  1851.             if ((arg = get_var(LEVEL_SET, ptr + 1)) != NULL) {
  1852.                if (cstat & ST_COND) {
  1853.                   char *tp;
  1854.                   tp = push_cpy(arg);
  1855.                   arg = tp;
  1856.                }
  1857.                else {
  1858.                   char *pe, sv, *index();
  1859.                   while (pe = index(arg,0xA0)) {
  1860.                      sv = *pe;
  1861.                      *pe = '\0';
  1862.                      av[ac++] = push_cpy(arg);
  1863.                      *pe = sv;
  1864.                      av[ac] = '\0';
  1865.                      arg = pe+1;
  1866.                   }
  1867.                }
  1868.             }
  1869.             else
  1870.                arg = ptr;
  1871.             break;
  1872.          case '*':
  1873.          case '?':
  1874.             if ((cstat & ST_NOEXP) == 0)
  1875.                doexpand = 1;
  1876.             arg = ptr;
  1877.             break;
  1878.          default:
  1879.             arg = ptr;
  1880.             break;
  1881.          }
  1882.  
  1883.          /* Append arg to av[ac] */
  1884.  
  1885.          for (scr = arg; *scr; ++scr)
  1886.             *scr &= 0x7F;
  1887.          if (av[ac]) {
  1888.             register char *old = av[ac];
  1889.             av[ac] = mpush(strlen(arg)+strlen(av[ac]));
  1890.             strcpy(av[ac], old);
  1891.             strcat(av[ac], arg);
  1892.          } else {
  1893.             av[ac] = push_cpy(arg);
  1894.          }
  1895.          if (elast != 0x80)
  1896.             break;
  1897.       }
  1898.  
  1899.       /* process expansion */
  1900.  
  1901.       if (doexpand) {
  1902.          char **eav, **ebase;
  1903.          int eac;
  1904.          has_wild = 1;
  1905.          eav = ebase = expand(av[ac], &eac);
  1906.          inc = 0;
  1907.          if (eav) {
  1908.             if (ac + eac + 2 > MAXAV) {
  1909.                ierror (NULL, 506);
  1910.                err = 1;
  1911.             } else {
  1912.                QuickSort(eav, eac);
  1913.                for (; eac; --eac, ++eav)
  1914.                   av[ac++] = push_cpy(*eav);
  1915.             }
  1916.             free_expand (ebase);
  1917.          }
  1918.       }
  1919.  
  1920.       /* process redirection  */
  1921.  
  1922.       if (redir && !err) {
  1923.          register char *file = (doexpand) ? av[--ac] : av[ac];
  1924.  
  1925.          if (redir < 0)
  1926.             Cin_name = file;
  1927.          else {
  1928.             Cout_name = file;
  1929.             Cout_append = (redir == 2);
  1930.          }
  1931.          inc = 0;
  1932.       }
  1933.  
  1934.       /* check elast for space */
  1935.  
  1936.       if (inc) {
  1937.          ++ac;
  1938.          if (ac + 2 > MAXAV) {
  1939.             ierror (NULL, 506);
  1940.             err = 1;                /* error condition */
  1941.             elast = 0;              /* don't process any more arguemnts */
  1942.          }
  1943.       }
  1944.       if (elast == ' ')
  1945.          goto step5;
  1946.    }
  1947. stepdone:
  1948.    av[ac] = '\0';
  1949.  
  1950.    /* process pipes via files */
  1951.  
  1952.    if (elast == '|' && !err) {
  1953.       static int which;             /* 0 or 1 in case of multiple pipes */
  1954.       which = 1 - which;
  1955.       Cout_name = (which) ? Pipe1 : Pipe2;
  1956.       Cout_ispipe = 1;
  1957.    }
  1958.  
  1959.  
  1960.    if (err)
  1961.       goto done0;
  1962.  
  1963.    {
  1964.       register int i;
  1965.       char save_elast;
  1966.       char *compile_av();
  1967.       register char *avline;
  1968.       unsigned char delim = ' ';
  1969.  
  1970.       save_elast = elast;
  1971.       if (pend_alias || (cmd_stat(command) & ST_AV))
  1972.          delim = 0xA0;
  1973.       avline = compile_av(av,((pend_alias) ? 1 : 0), ac , delim);
  1974.  
  1975.  
  1976.       if (pend_alias) {                               /* special % alias */
  1977.          register char *ptr, *scr;
  1978.          for (ptr = pend_alias; *ptr && *ptr != ' '; ++ptr);
  1979.          set_var (LEVEL_SET, pend_alias + 1, avline);
  1980.          free (avline);
  1981.  
  1982.          scr = malloc((strlen(ptr) << 2) + 2);
  1983.          preformat (ptr, scr);
  1984.          fcomm (scr, 1);
  1985.          unset_var (LEVEL_SET, pend_alias + 1);
  1986.       } else {                                        /* normal command  */
  1987.          register int ccno;
  1988.          long  oldcin  = Myprocess->pr_CIS;
  1989.          long  oldcout = Myprocess->pr_COS;
  1990.          char *Cin_buf;
  1991.          struct FileHandle *ci;
  1992.          long oldbuf;
  1993.  
  1994.          fflush(stdout);
  1995.          ccno = find_command (command);
  1996.          if ((Command[ccno].stat & (ST_NORED | ST_COND)) == 0) {
  1997.             if (Cin_name) {
  1998.                if ((Cin = (long)extOpen(Cin_name,1005L)) == 0L) {
  1999.                   ierror (NULL, 504);
  2000.                   err = 1;
  2001.                   Cin_name = '\0';
  2002.                } else {
  2003.                   Myprocess->pr_CIS = _devtab[stdin->_unit].fd = Cin;
  2004.                   ci = (struct FileHandle *)(((long)Cin)<<2);
  2005.                   Cin_buf = (char *)AllocMem(202L, MEMF_PUBLIC);
  2006.                   oldbuf = ci->fh_Buf;
  2007.                   if (ci->fh_Buf == 0) /* fexec expects a CIS buffer */
  2008.                      ci->fh_Buf = (long)Cin_buf>>2;
  2009.                }
  2010.             }
  2011.             if (Cout_name) {
  2012.                if (Cout_append && (Cout =(long)extOpen(Cout_name, 1005L)) ) {
  2013.                      Seek(Cout, 0L, 1L);
  2014.                } else {
  2015.                   Cout = (long)extOpen(Cout_name,1006L);
  2016.                }
  2017.                if (Cout == NULL) {
  2018.                   err = 1;
  2019.                   ierror (NULL, 504);
  2020.                   Cout_name = '\0';
  2021.                   Cout_append = 0;
  2022.                } else {
  2023.                   Myprocess->pr_COS = _devtab[stdout->_unit].fd = Cout;
  2024.                }
  2025.             }
  2026.          }
  2027.          if (ac < Command[ccno].minargs + 1) {
  2028.             ierror (NULL, 500);
  2029.             err = -1;
  2030.          } else if (!err) {
  2031.             i = (*Command[ccno].func)(avline, Command[ccno].val);
  2032.             if (i < 0)
  2033.                i = 20;
  2034.             err = i;
  2035.          }
  2036.          free (avline);
  2037.          if (E_stack == 0 && Lastresult != err) {
  2038.             Lastresult = err;
  2039.             seterr();
  2040.          }
  2041.          if ((Command[ccno].stat & (ST_NORED | ST_COND)) == 0) {
  2042.             if (Cin_name) {
  2043.                fflush(stdin);
  2044.                clearerr(stdin);
  2045.                ci->fh_Buf = oldbuf;
  2046.                extClose(Cin);
  2047.                FreeMem(Cin_buf, 202L);
  2048.             }
  2049.             if (Cout_name) {
  2050.                fflush(stdout);
  2051.                clearerr(stdout);
  2052.                stdout->_flags &= ~_DIRTY;    /* because of nil: device */
  2053.                extClose(Cout);
  2054.                Cout_append = 0;
  2055.             }
  2056.          }
  2057.          Myprocess->pr_CIS =  _devtab[stdin->_unit].fd  = oldcin;
  2058.          Myprocess->pr_COS =  _devtab[stdout->_unit].fd = oldcout;
  2059.       }
  2060.  
  2061.       if (Cin_ispipe && Cin_name)
  2062.          DeleteFile(Cin_name);
  2063.       if (Cout_ispipe) {
  2064.          Cin_name = Cout_name;         /* ok to assign.. static name */
  2065.          Cin_ispipe = 1;
  2066.       } else {
  2067.          Cin_name = '\0';
  2068.       }
  2069.       Cout_name = '\0';
  2070.       Cout_ispipe = 0;
  2071.       elast = save_elast;
  2072.    }
  2073.    mpop_tobase();                      /* free arguments   */
  2074.    mpush_base();                       /* push dummy base  */
  2075.  
  2076. done0:
  2077.    {
  2078.       char *str;
  2079.       if (err && E_stack == 0) {
  2080.          str = get_var(LEVEL_SET, v_except);
  2081.          if (err >= ((str)?atoi(str):1)) {
  2082.             if (str) {
  2083.                ++H_stack;
  2084.                ++E_stack;
  2085.                exec_command(str);
  2086.                --E_stack;
  2087.                --H_stack;
  2088.             } else {
  2089.                Exec_abortline = 1;
  2090.             }
  2091.          }
  2092.       }
  2093.       if (elast != 0 && Exec_abortline == 0)
  2094.          err = fcomm(nextstr, 0);
  2095.       Exec_abortline = 0;
  2096.       if (Cin_name)
  2097.          DeleteFile(Cin_name);
  2098.       Cin_name = NULL;
  2099.       Cin_ispipe = 0;
  2100.    }
  2101. done1:
  2102.    mpop_tobase();
  2103.    if (freeok)
  2104.       free(str);
  2105.    --alias_count;
  2106.    return ((int)err);                  /* TRUE = error occured    */
  2107. }
  2108.  
  2109.  
  2110. char *
  2111. exarg(ptr)
  2112. unsigned char **ptr;
  2113. {
  2114.    register unsigned char *end;
  2115.    register unsigned char *start;
  2116.  
  2117.    start = end = *ptr;
  2118.    while (*end && *end != 0x80 && *end != ';' && *end != '|' && *end != ' ')
  2119.       ++end;
  2120.    elast = *end;
  2121.    *end = '\0';
  2122.    *ptr = end + 1;
  2123.    return ((char *)start);
  2124. }
  2125.  
  2126. static char **Mlist;
  2127.  
  2128. mpush_base()
  2129. {
  2130.    char *str;
  2131.  
  2132.    str = malloc(5);
  2133.    *(char ***)str = Mlist;
  2134.    str[4] = 0;
  2135.    Mlist = (char **)str;
  2136. }
  2137.  
  2138. char *
  2139. mpush(bytes)
  2140. {
  2141.    char *str;
  2142.  
  2143.    str = malloc(6 + bytes + 2);   /* may need extra 2 bytes in do_run() */
  2144.    *(char ***)str = Mlist;
  2145.    str[4] = 1;
  2146.    Mlist = (char **)str;
  2147.    return (str + 5);
  2148. }
  2149.  
  2150. mpop_tobase()
  2151. {
  2152.    register char *next;
  2153.    while (Mlist) {
  2154.       next = *Mlist;
  2155.       if (((char *)Mlist)[4] == 0) {
  2156.          free (Mlist);
  2157.          Mlist = (char **)next;
  2158.          break;
  2159.       }
  2160.       free (Mlist);
  2161.       Mlist = (char **)next;
  2162.    }
  2163. }
  2164.  
  2165.  
  2166. /*
  2167.  * Insert 'from' string in front of 'str' while deleting the
  2168.  * first entry in 'str'.  if freeok is set, then 'str' will be
  2169.  * free'd
  2170.  */
  2171.  
  2172.  
  2173.  
  2174. char *
  2175. format_insert_string(str, from, freeok)
  2176. char *str;
  2177. char *from;
  2178. int *freeok;
  2179. {
  2180.    register char *new1, *new2;
  2181.    register unsigned char *strskip;
  2182.    int len;
  2183.  
  2184.    for (strskip = (unsigned char *)str;
  2185.                    *strskip && *strskip != ' ' 
  2186.                    && *strskip != ';' && *strskip != '|'
  2187.                    && *strskip != 0x80; ++strskip);
  2188.    len = strlen(from);
  2189.    new1 = malloc((len << 2) + 2);
  2190.    preformat(from, new1);
  2191.    len = strlen(new1) + strlen(strskip);
  2192.    new2 = malloc(len+2);
  2193.    strcpy(new2, new1);
  2194.    strcat(new2, strskip);
  2195.    new2[len+1] = 0;
  2196.    free (new1);
  2197.    if (*freeok)
  2198.       free (str);
  2199.    *freeok = 1;
  2200.    return (new2);
  2201. }
  2202.  
  2203. cmd_stat(str)
  2204. char *str;
  2205. {
  2206.    return(Command[find_command(str)].stat);
  2207. }
  2208.  
  2209. find_command(str)
  2210. char *str;
  2211. {
  2212.    register unsigned int i;
  2213.    int len = strlen(str);
  2214.  
  2215.    if (*str >= '0'  &&  *str <= '9')
  2216.       return (1);
  2217.    for (i = 0; Command[i].func; ++i) {
  2218.       if (strncmp (str, Command[i].name, len) == 0)
  2219.          return (i);
  2220.    }
  2221.    return (0);
  2222. }
  2223.  
  2224. do_help()
  2225. {
  2226.    register struct COMMAND *com;
  2227.    int i= 0;
  2228.  
  2229.  
  2230.    for (com = &Command[2]; com->func; ++com) {
  2231.       printf ("%-12s", com->name);
  2232.       if (++i  % 6 == 0) printf("\n");
  2233.    }
  2234.    printf("\n");
  2235.    return(0);
  2236. }
  2237.  
  2238. char *push_cpy(s)
  2239. char *s;
  2240. {
  2241. return strcpy(mpush(strlen(s)), s);
  2242. }
  2243. SHAR_EOF
  2244. #    End of shell archive
  2245. exit 0
  2246. -- 
  2247. Bob Page, U of Lowell CS Dept.  page@swan.ulowell.edu  ulowell!page
  2248. Have five nice days.
  2249.